#include "crypt.h"
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <memory.h>

#define BUFSIZE 4096

void usage() {
  printf("usage: \n");
  printf("encrypt: aes -e file -p password -o outfile\n");
  printf("decrypt: aes -d file -p password -o outfile\n");
}

int main(int argc,char **argv) {
  if(argc!=7||(strcmp(argv[1],"-e")!=0&&strcmp(argv[1],"-d"))||strcmp(argv[3],"-p")!=0||strcmp(argv[5],"-o")!=0) {
    usage();
    return 0;
  }

  //用口令生成aes_key
  char key[AES_KEY_LEN/8];
  generate_aeskey_by_passwd(argv[4],strlen(argv[4]),key);
  //初始向量
  char ivec[]=IVEC;

  int r_fd = open(argv[2], O_RDONLY);
  int w_fd = open(argv[6], O_WRONLY | O_CREAT | O_TRUNC,00600);
  if(r_fd==-1||w_fd==-1) {
    printf("failed to open file\n");
    return 0;
  }

  int len;
  char read_buf[BUFSIZE+256]={0} , write_buf[BUFSIZE+256]={0};
  //加密或解密
  if(strcmp(argv[1],"-e")==0) {
    while((len=read(r_fd,read_buf,sizeof(read_buf)))>0) {
      if(len<BUFSIZE) {
        //使用PKCS7填充
        size_t padd_num = 16 - len % 16;
        for(int i=0;i<padd_num;i++)
          read_buf[len++]=padd_num;
      }
      len=aes_encrypt(read_buf, len, write_buf, key, ivec);
      write(w_fd,write_buf,len);
    }
  } else {
    int temp;//记录write_buf在最后一次加密中的密文长度
    while((len=read(r_fd,read_buf,sizeof(read_buf)))>0) {
      aes_decrypt(read_buf,len,write_buf,key, ivec);
      write(w_fd,write_buf,len);
      temp = len;
    }
    //去填充
    len = lseek(w_fd,0,SEEK_END);
    ftruncate(w_fd,len-(int)(write_buf[temp-1]));
  }

  close(r_fd); close(w_fd);
  return 0;
}
